package test.util

import scala.collection.immutable.Map
import org.specs2.matcher.Expectable
import org.specs2.matcher.Matcher

class Timeline {
  private val lock = new Object
  private var counter = 0
  private var events = Map[String, TimelineEvent]()
  
  def apply(name: String): TimelineEvent = lock.synchronized {
    assert(events.contains(name))
    events(name)
  }

  def define(name: String): TimelineEvent = lock.synchronized {
    assert(!events.contains(name))
    val event = new TimelineEvent(name, counter)
    counter += 1
    events += (name -> event)
    event
  }
}

object Timeline {
  def precede(a: => TimelineEvent) = new Matcher[TimelineEvent](){
    def apply[S <: TimelineEvent](left: Expectable[S]) = {
      val right = a;
      result(
        left.value.index < right.index,
        "event \"" + left.value.name + "\" precedes event \"" + right.name +"\"",
        "event \"" + left.value.name + "\" does not precede event \"" + right.name +"\"",
        left)
    }
  }

  def follow(a: => TimelineEvent) = new Matcher[TimelineEvent](){
    def apply[S <: TimelineEvent](left: Expectable[S]) = {
      val right = a;
      result(
        left.value.index > right.index,
        "event \"" + left.value.name + "\" precedes event \"" + right.name +"\"",
        "event \"" + left.value.name + "\" does not precede event \"" + right.name +"\"",
        left)
    }
  }
}
